﻿using System;

namespace SystemX
{
	/// <summary>
	/// Extension methods
	/// </summary>
	/// <remarks>for object </remarks>
	public partial class ObjectX
	{

		/// <summary>
		/// obj to Generic Type conversion.Return default(T) if an exception accurs
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="obj"></param>
		/// <returns></returns>
		public static T As<T>(this object obj)
		{
			return obj.As<T>(true);
		}
		/// <summary>
		/// obj to Generic Type conversion.
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="obj"></param>
		/// <param name="suppressError">suppress exception</param>
		/// <returns></returns>
		public static T As<T>(this object obj, bool suppressError)
		{
			var retVal = default(T);
			try
			{
				//special for emun
				if (typeof(T).IsEnum)
				{
					retVal = (T)Enum.Parse(typeof(T), obj.ToString());
				}
				else if (typeof(T) == typeof(Guid)) {
					obj=new Guid(obj.ToString());
					retVal = (T)obj;
				}else
				{
					retVal = (T)obj;
				}

			}
			catch (FormatException e1)//more try
			{
				retVal = (T)Convert.ChangeType(obj, typeof(T));
			}
			catch (InvalidCastException e2)//more more try 
			{
				retVal = (T)Convert.ChangeType(obj, typeof(T));
			}
			catch (Exception ex)//oh no...
			{
				if (!suppressError) throw ex;
			}
			return retVal;
		}
		/// <summary>
		/// obj to Generic Type conversion.Return default(T) if an exception accurs
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="obj"></param>
		/// <param name="formatProvider"></param>
		/// <returns></returns>
		public static T As<T>(this object obj, IFormatProvider formatProvider)
		{
			return obj.As<T>(formatProvider, true);
		}
		/// <summary>
		/// obj to Generic Type conversion.
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="obj"></param>
		/// <param name="formatProvider"></param>
		/// <param name="suppressError"></param>
		/// <returns></returns>
		public static T As<T>(this object obj, IFormatProvider formatProvider, bool suppressError)
		{
			var retVal = default(T);
			try
			{
				//special for emun
				if (typeof(T).IsEnum)
				{
					retVal = (T)Enum.Parse(typeof(T), obj.ToString());
				}
				else
				{
					retVal = (T)obj;
				}

			}
			catch (FormatException e1)//more try
			{
				retVal = (T)Convert.ChangeType(obj, typeof(T),formatProvider);
			}
			catch (InvalidCastException e2)//more more try 
			{
				retVal = (T)Convert.ChangeType(obj, typeof(T),formatProvider);
			}
			catch (Exception ex)//oh no...
			{
				if (!suppressError) throw ex;
			}
			return retVal;
		}
	}
}
